package cn.lix.sc.rpc.client.config;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;

/**
 * mock返回数据。开启功能在idea启动参数中配置：-Drequest.mock.enable=true
 * @Author 木林森
 * @Date 2021/7/22
 */
@Configuration
public class MockHandlerInterceptor extends HandlerInterceptorAdapter implements WebMvcConfigurer {

    private final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(this.getClass());

    /**
     * 在JVM中配置启动参数增加-Dwp.baseline.mock.enable=true（该参数只能在本地调试环境使用）
     * 开启mock
     */
    @Value("${request.mock.enable:false}")
    private Boolean openMock;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(this);
        WebMvcConfigurer.super.addInterceptors(registry);
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!openMock) {
            return true;
        }
        // 非ajax请求
//        if (request.getHeader("x-requested-with") == null || !request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
//            return true;
//        }
        // mock配置的key规则：请求路径_GET/POST/PUT/DELETE
        String mockKey = request.getRequestURI().concat("_").concat(request.getMethod());
        String mockData = getMockData(mockKey);
        if (StringUtils.isEmpty(mockData)) {
            return true;
        }

        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            writer.print(mockData);
        } catch (IOException e) {
            log.error("response error", e);
        } finally {
            if (writer != null) {
                writer.close();
                writer = null;
            }
        }
        return false;
    }

    private String getMockData(String key){
        Map<String, Object> cacheMap;
        try {
            // 每次都实时从文件读取，方便修改
            cacheMap = new ObjectMapper().readValue(ResourceUtils.getFile("classpath:mock.json"), Map.class);
        } catch (IOException e) {
            log.error("解析mock.json出错");
            cacheMap = Collections.emptyMap();
        }
        Object resultJson = cacheMap.get(key);
        if(Objects.isNull(resultJson)){
            log.info("未配置请求{}对应的mock数据", key);
            return null;
        }
        return JSON.toJSONString(resultJson);
    }

}
